﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using QuadRemote.Core;

namespace QuadRemote.Tabs
{
    
    public partial class GraphPropertyWindow : Form
    {
        GraphFrame frame;
        public GraphPropertyWindow(GraphFrame frame)
        {
            this.frame = frame;
            InitializeComponent();

            lstAvailable.Sorted = true;
            lstActive.Sorted = true;

            txtRightMax.Text = Tools.floatToString(frame.primaryMax);
            txtRightMin.Text = Tools.floatToString(frame.primaryMin);
            txtLeftMax.Text = Tools.floatToString(frame.secundaryMax);
            txtLeftMin.Text = Tools.floatToString(frame.secundaryMin);

            chAllowOffset.Checked = frame.allowOffsets;
            chAutoscale.Checked = frame.autoScale;
            chRightDisplay.Checked = frame.primaryDraw;
            chLeftDisplay.Checked = frame.secundaryDraw;
            chLeftRightSame.Checked = frame.axisSameZero;
            chHorizontal.Checked = frame.drawHorizontal;

            txtLeftMax.KeyPress += txtNumericPress;
            txtLeftMin.KeyPress += txtNumericPress;
            txtRightMax.KeyPress += txtNumericPress;
            txtRightMin.KeyPress += txtNumericPress;

            chAllowOffset.CheckedChanged += recalculate;
            chAutoscale.CheckedChanged += recalculate;
            chLeftRightSame.CheckedChanged += recalculate;
            txtLeftMax.LostFocus += recalculate;
            txtLeftMax.LostFocus += recalculate;
            txtLeftMin.LostFocus += recalculate;
            txtRightMax.LostFocus += recalculate;
            txtRightMin.LostFocus += recalculate;

            setRules();
        }

        void recalculate(object sender, EventArgs e)
        {
            setRules();
        }

        void txtNumericPress(object sender, KeyPressEventArgs e)
        {
            if (!char.IsControl(e.KeyChar)
                && !char.IsDigit(e.KeyChar)
                && ((e.KeyChar != '.'))
                && ((e.KeyChar != '-')))
            {
                e.Handled = true;
            }

            if (e.KeyChar == '.'
                && (sender as TextBox).Text.IndexOf('.') > -1)
            {
                e.Handled = true;
            }
        }

        private void setRules()
        {
            float lMax, rMax, lMin, rMin;
            try
            {
                lMax = float.Parse(txtLeftMax.Text);
                rMax = float.Parse(txtRightMax.Text);
                lMin = float.Parse(txtLeftMin.Text);
                rMin = float.Parse(txtRightMin.Text);
            }
            catch (Exception e)
            {
                return;
            }
            if (lMax <= lMin) lMax = lMin + 1;
            if (rMax <= rMin) rMax = rMin + 1;

            if (!chAllowOffset.Checked)
            {
                if (lMax < 0) lMax = 0;
                if (rMax < 0) rMax = 0;
                if (lMin > 0) lMin = 0;
                if (rMin > 0) rMin = 0;
            }

            txtLeftMax.Enabled = !chAutoscale.Checked;
            txtRightMax.Enabled = !chAutoscale.Checked;
            txtLeftMin.Enabled = !chAutoscale.Checked;
            txtRightMin.Enabled = !chAutoscale.Checked;

            if (chLeftRightSame.Checked)
            {
                // primary scale contains '0'
                if (rMin <= 0 && rMax >= 0)
                {
                    float p = rMax / (rMax - rMin);

                    if (p == 0)
                    {
                    }
                    else
                        lMin = lMax - lMax / p;
                }
                else if (rMin < 0 && rMax < 0)
                {

                }
            }

            txtLeftMax.Text = Tools.floatToString(lMax);
            txtRightMax.Text = Tools.floatToString(rMax);
            txtLeftMin.Text = Tools.floatToString(lMin);
            txtRightMin.Text = Tools.floatToString(rMin);
        }

        private void GraphPropertyWindow_Load(object sender, EventArgs e)
        {
            Dictionary<Byte, LogValueContainer> values = FlightSession.current().Log.values;
            //LogValueContainer test = new LogValueContainer((byte)0,"test[x,y,z]");
            //test.numValues = 3;
            //values.Add((byte)values.Keys.Count, test);

            foreach (Byte b in values.Keys)
            {
                LogValueContainer c = values[b];

                for (int i=0;i<c.numValues;i++)
                {
                    bool added = false;
                    foreach (LogValueGraph graph in frame.plots)
                    {
                        if (graph.container == c && graph.containerValue == i)
                        {
                            lstActive.Items.Add(new GraphListItem(c, i));
                            added = true;
                            break;
                        }
                    }
                    if (!added) lstAvailable.Items.Add(new GraphListItem(c, i));

                }
            }
        }

        private void btAdd_Click(object sender, EventArgs e)
        {
            if (lstAvailable.SelectedIndex >= 0)
            {
                GraphListItem item = (GraphListItem)lstAvailable.SelectedItem;

                lstAvailable.Items.Remove(item);
                lstActive.Items.Add(item);

                frame.addPlot(item.container, item.index);

                lstAvailable.SelectedIndex = -1;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (lstActive.SelectedIndex >= 0)
            {
                GraphListItem item = (GraphListItem)lstActive.SelectedItem;

                lstActive.Items.Remove(item);
                lstAvailable.Items.Add(item);

                frame.removePlot(item.container, item.index);

                lstActive.SelectedIndex = -1;
            }
        }

        private void lstAvailable_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void lstAvailable_DoubleClick(object sender, EventArgs e)
        {
            btAdd_Click(sender, e);
        }

        private void lstActive_DoubleClick(object sender, EventArgs e)
        {
            button1_Click(sender, e);
        }

        private void btApply_Click(object sender, EventArgs e)
        {
            frame.primaryDraw = chRightDisplay.Checked;
            frame.secundaryDraw = chLeftDisplay.Checked;
            frame.primaryMin = float.Parse(txtRightMin.Text);
            frame.primaryMax = float.Parse(txtRightMax.Text);
            frame.secundaryMin = float.Parse(txtLeftMin.Text);
            frame.secundaryMax = float.Parse(txtLeftMax.Text);
            frame.allowOffsets = chAllowOffset.Checked;
            frame.axisSameZero = chLeftRightSame.Checked;
            frame.drawHorizontal = chHorizontal.Checked;
            frame.autoScale = chAutoscale.Checked;
        }
    }

    class GraphListItem
    {
        public String name;
        public int index;
        public LogValueContainer container;

        public GraphListItem(LogValueContainer c, int index)
        {
            this.name = c.getName(index);
            this.index = index;
            this.container = c;
        }

        public override string ToString()
        {
            return name;
        }

    }
}
